/** swi.c: SWI-related functions
 *
 * Author: 	Nora Tarano <ntarano@andrew.cmu.edu>
 *          Yuan Meng <yuanm@andrew.cmu.edu>
 *          Yipeng Yun <yipengy@andrew.cmu.edu>
 * Date: 	Dec 11, 2011
 */
#include <types.h>
#include <exports.h>
#include <syscall.h>
#include <lock.h>

#include <arm/psr.h>
#include <arm/swi.h>
#include <arm/exception.h>

#include <bits/swi.h>

#include "arm/handler.h"

#define SWI_VECTOR_ADDR	(unsigned int*)0x08

unsigned int old_swi_instructions[2];
extern int swi_handler();

void init_swi(void)
{
	install_handler((unsigned int) swi_handler, SWI_VECTOR_ADDR, old_swi_instructions);
}

void destroy_swi(void)
{
	uninstall_handler(SWI_VECTOR_ADDR, old_swi_instructions);
}

void swi_dispatch(unsigned int swi_num, struct ex_context* c)
{
	
	// make appropriate syscalls
	switch (swi_num) 
	{
		case READ_SWI:
			c->r0 = read_syscall(c->r0, (char *)(c->r1), c->r2);
			break;
		case WRITE_SWI:
			c->r0 = write_syscall(c->r0, (char *)(c->r1), c->r2);
			break;
		case SLEEP_SWI:
			sleep_syscall(c->r0);
			break;
		case TIME_SWI:
			c->r0 = time_syscall();
			break;
		case CREATE_SWI:
			c->r0 = task_create((task_t *) c->r0, (size_t) c->r1);
			break;
		case MUTEX_CREATE:
			c->r0 = mutex_create();
			break;
		case MUTEX_LOCK:
			c->r0 = mutex_lock((int) c->r0);
			break;
		case MUTEX_UNLOCK:
			c->r0 = mutex_unlock((int) c->r0);
			break;
		case EVENT_WAIT:
			c->r0 = event_wait((unsigned int) c->r0);
			break;
		default: 
			invalid_syscall(swi_num);
	}
}
